/********************************** (C) COPYRIGHT *******************************
* File Name          : driver.h
* Author             : nx666
* Version            : V1.0.0
* Date               : 2023/02/27
* Description        : 所依赖的mcu外设在这里声明接口.
*******************************************************************************/
#ifndef __DRIVER_H
#define __DRIVER_H

#include "IQmathLib.h"
#ifdef __cplusplus
extern "C" {
#endif
#include "ch32f20x.h"
#include "common_type.h"
#include "FreeRTOS.h"
#include "semphr.h"

/* 宏定义区 */

#define DMA_BUF_LEN                 (0x1 << FOC_SAMPLING_ARRAY_LEN)

#define FOC_TIM_OUTTIME             (FOC_CALC_CYCLE)  //定时器超时时间 单位：us
#define PWM_DEFAULT_ARR             2500
#define PWM_DEFAULT_FREQ            56000
#define PWM_DEFAULT_ARR_LIMIT       1250
#define PWM_DEAD_TIME               20
#define foc_msgRxBufWrite          USART2_IRQHandler
#define foc_recvMsg                USART2_idleIRQClear
#define foc_timIrq                 TIM3_IRQHandler

/*类型定义区*/

typedef struct {
    void (*setupLed)(void);
    void (*downLed)(void);
}workLed_;

typedef struct tim{
    uInt16 timOutTime;
    int (*setOutTime)(struct tim *,int);
    void (*clearIrq)(void);
    void (*startTim)(void);
}tim_;

typedef struct pwm{
    uInt16  frequency;        //开关频率
    uInt16  deadTime;        //真实死区时间 = deadTime/10000*1/frequency
    uInt32  frameCount;      //帧计数
    uInt16  pwmA;            //记录 a相设置的占空比
    uInt16  pwmB;            //记录 b相设置的占空比
    uInt16  pwmC;            //记录 c相设置的占空比
    int (*set3PhasePwm)(struct pwm *,uInt16,uInt16,uInt16);
}pwm_;

typedef struct adc{
    uInt32    *adcValBuf;                      //采样数据缓冲区 第一路16bit数据 + 第二路16bit数据 + 第一路16bit数据 ... 交替存放
    uInt16     bufLen;                         //缓冲区长度
    uInt16     calibrattionVal1;               //第一路采样值校准
    uInt16     calibrattionVal2;               //第二路采样值校准
    uInt8      adcBitWidth;                    //adc位宽
    _iq        refV;                           //参考电压 mV
    _iq        convertK1;                      //adc值到电流的转化系数
    _iq        convertK2_a;                      //adc值到电流的转化系数
    _iq        convertK2_b;                      //adc值到电流的转化系数
    _iq        convertK2_c;                      //adc值到电流的转化系数
    _iq        Ia;
    _iq        Ib;                               // A
    _iq        Ic;
    Int        (*getCurrentIaIbIc)(struct adc*); //获取电机当前线电流 单位A
}adc_;


/*********************************************************************
 * @fn      workLedCreate
 *
 * @brief   创建工作灯
 *              void
 *
 * @return  成功，workLed *；  失败，NULL
 *          
 */
workLed_ *workLedCreate(void);

/*********************************************************************
 * @fn      creatFocTim
 *
 * @brief   创建foc定时器.
 *
 * @param   void
 *         
 * @return  tim_ *，成功  NULL，失败
 */
tim_ *creatFocTim(void);

/*********************************************************************
 * @fn      creatFocTim
 *
 * @brief   创建foc定时器.
 *
 * @param   void
 *         
 * @return  tim_ *，成功  NULL，失败
 */
pwm_ *creatPwm(void);

/*********************************************************************
 * @fn      createAdc
 *
 * @brief   创建adc.
 *
 * @param   void
 *         
 * @return  adc_ *，成功  NULL，失败
 */
adc_ *createAdc(void);

/*********************************************************************
 * @fn      serialInit
 *
 * @brief   Initializes the USARTx peripheral.
 *
 * @param   baudrate - USART communication baud rate.
 *
 * @return  None
 */
void serialInit(u32 baudrate);

/*********************************************************************
 * @fn      logSend
 *
 * @brief   发送一段log.
 *
 * @param   pBuffer - log地址. size - 待发送log的长度
 *
 * @return  None
 */
void logSend(uInt8 *pBuffer, int size);

/*********************************************************************
 * @fn      uartSend
 *
 * @brief   uart发送一段数据.
 *
 * @param   pBuffer - 数据地址. size - 待发送数据的长度
 *
 * @return  None
 */
void uartSend(uInt8 *pBuffer, int size);

/*********************************************************************
 * @fn      uartRecv
 *
 * @brief   uart开启接收数据.
 *
 * @param   pBuffer - 数据保存地址. size - 可使用的缓存的长度
 *
 * @return  None
 */
void uartRecv(uInt8 *pBuffer, int size);

/*********************************************************************
 * @fn      USART2_idleIRQClear
 *
 * @brief   清除usart2空闲中断标记中断标记.
 *
 * @param   
 *
 * @return  返回dma传输的数据字节计数
 */
int USART2_idleIRQClear();

#ifdef __cplusplus
}
#endif

#endif /*__DRIVER_H */